// SocketTestFrame.cpp : implementation of the CSocketTestFrame class
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#ifdef WIN32_PLATFORM_PSPC
#include "resourceppc.h"
#else
#include "resourcesp.h"
#endif

#include "aboutdlg.h"
#include "SocketTestView.h"
#include "SocketTestFrame.h"

#include "CETool.h"
#include "MService.h"
#include "ISocketManager.h"

const GUID IID_DestNetWAP = {0x7022e968, 0x5a97, 0x4051, {0xbc, 0x1c, 0xc5, 0x78, 0xe2, 0xfb, 0xa5, 0xd9}};

const LPCSTR lpszSocketAddr[] = {"221.130.10.215", "221.130.10.216", "221.130.10.217", "221.130.10.218"};
const int	iSocketPort[]	= {29999, 30000, 30001, 30002, 30003};
const int	iAddrs			= sizeof(lpszSocketAddr)/sizeof(LPCSTR);
const int	iPorts			= sizeof(iSocketPort)/sizeof(DWORD);

BOOL CSocketTestFrame::PreTranslateMessage(MSG* pMsg)
{
	if(CFrameWindowImpl<CSocketTestFrame>::PreTranslateMessage(pMsg))
		return TRUE; 

	return m_view.IsWindow() ? m_view.PreTranslateMessage(pMsg) : FALSE;
}

bool CSocketTestFrame::AppHibernate(bool bHibernate)
{
	// Insert your code here or delete member if not relevant
	return bHibernate;
}

bool CSocketTestFrame::AppNewInstance(LPCTSTR /*lpstrCmdLine*/)
{
	// Insert your code here or delete member if not relevant
	return false;
}

void CSocketTestFrame::AppSave()
{
	CAppInfo info;
	// Insert your code here
}

#ifdef WIN32_PLATFORM_WFSP
	void CSocketTestFrame::AppBackKey() 
{
	::SHNavigateBack();
}
#endif

BOOL CSocketTestFrame::OnIdle()
{
	UIUpdateToolBar();
	return FALSE;
}

LRESULT CSocketTestFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	CAppInfo info;

#ifdef WIN32_PLATFORM_PSPC // PPC
	OSVERSIONINFO osvi;
	GetVersionEx(&osvi);
	if (osvi.dwMajorVersion >= 5)
		CreateSimpleCEMenuBar();
	else
		CreateSimpleCEMenuBar(IDR_MAINFRAME, 0, IDR_MAINFRAME, 7);
#else // SmartPhone
	CreateSimpleCEMenuBar();
	AtlActivateBackKey(m_hWndCECommandBar);
#endif 
	UIAddToolBar(m_hWndCECommandBar);

	m_hWndClient = m_view.Create(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | LVS_REPORT | LVS_SHOWSELALWAYS);

	// register object for message filtering and idle updates
	CMessageLoop* pLoop = _Module.GetMessageLoop();
	ATLASSERT(pLoop != NULL);
	pLoop->AddMessageFilter(this);
	pLoop->AddIdleHandler(this);

	HANDLE hConnection = NULL;
	CETool::EstablishConnection(&IID_DestNetWAP, hConnection);

	ZeroMemory(&m_CurProc, sizeof(m_CurProc));

	m_view.AddColumn(_T("IP Address"), 0);
	m_view.AddColumn(_T("Port"), 1);
	m_view.AddColumn(_T("Connect Time"), 2);

	return 0;
}

LRESULT CSocketTestFrame::OnFileExit(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	PostMessage(WM_CLOSE);
	return 0;
}

void CSocketTestFrame::ExecuteOne()
{
	if ( m_CurProc.iAddr >= iAddrs )
	{
		if ( IDRETRY == ::MessageBox(NULL, _T("Last address!"), _T("Error"), MB_RETRYCANCEL) )
		{
			m_CurProc.iAddr = 0;
			m_CurProc.iPort = 0;

			MService::FreeSocketManager(m_CurProc.pManager);
			m_CurProc.pManager = NULL;

			m_view.DeleteAllItems();
		}
	}

	if ( NULL == m_CurProc.pManager )
	{
		m_CurProc.pManager = MService::CreateSocketManager(this);

		if ( NULL != m_CurProc.pManager && m_CurProc.pManager->OpenNet() )
		{
			m_CurProc.dwStart = ::GetTickCount();
			m_CurProc.pManager->Connect((const BYTE*)(lpszSocketAddr[m_CurProc.iAddr]),
										iSocketPort[m_CurProc.iPort]);

			SetTimer(100, 45000);
		}
	}
}

void CSocketTestFrame::ShowOne(LPCTSTR lpszResult)
{
	const int iItem	= m_CurProc.iAddr * iPorts + m_CurProc.iPort;
	CString strText(lpszSocketAddr[m_CurProc.iAddr]);
	m_view.AddItem(iItem, 0, strText);

	strText.Format(_T("%d"), iSocketPort[m_CurProc.iPort]);
	m_view.AddItem(iItem, 1, strText);

	m_view.AddItem(iItem, 2, lpszResult);
}

LRESULT CSocketTestFrame::OnAction(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	ExecuteOne();

	return 0;
}

LRESULT CSocketTestFrame::OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	CAboutDlg dlg;
	dlg.DoModal();
	return 0;
}

WORD CSocketTestFrame::OnReceive(const BYTE* /*pData*/, WORD /*wLen*/)
{
	return NULL;
}

void CSocketTestFrame::OnSend()
{

}

void CSocketTestFrame::MoveNext()
{
	if ( NULL != m_CurProc.pManager )
	{
		MService::FreeSocketManager(m_CurProc.pManager);
		m_CurProc.pManager = NULL;
	}

	if ( m_CurProc.iPort < iPorts - 1 )
	{
		++(m_CurProc.iPort);
	}
	else
	{
		++(m_CurProc.iAddr);
		m_CurProc.iPort = 0;
	}
}

void CSocketTestFrame::OnConnected()
{
	DWORD dwSpan = (::GetTickCount() - m_CurProc.dwStart) * 10;
	CString strText;
	strText.Format(_T("%d"), dwSpan);

	ShowOne(strText);

	MoveNext();

	ExecuteOne();
}

void CSocketTestFrame::OnError(int /*iErrCode*/)
{
	ShowOne(_T("Connect Failed"));

	MoveNext();

	ExecuteOne();
}

LRESULT CSocketTestFrame::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
	// TODO: Add your message handler code here and/or call default

	return ::DefWindowProc(m_hWnd, uMsg, wParam, lParam);
}

LRESULT CSocketTestFrame::OnFileSave(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	// TODO: Add your command handler code here

	return 0;
}

LRESULT CSocketTestFrame::OnTimer(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	// TODO: Add your message handler code here and/or call default
	KillTimer(100);

	if ( NULL != m_CurProc.pManager )
	{
		ShowOne(_T("Connection Failed!"));

		MoveNext();
		ExecuteOne();
	}

	return 0;
}
